import javax.swing.*;
import javax.swing.table.AbstractTableModel;

import java.util.ArrayList;
import java.awt.event.*;
import java.awt.*;
import java.util.*;

class JournalTableModel extends AbstractTableModel {

	private Bridget bridget;
	private String[] columnNames = { "Date", "Activity", "Calories" };

	
	public JournalTableModel(Bridget bridget) {
		this.bridget = bridget;
	}
	
    public int getColumnCount() {
        return 3;
    }

    public int getRowCount() {
    	return bridget.getLog().size();
    }

    public String getColumnName(int col) {
        return columnNames[col];
    }

    public Object getValueAt(int row, int col) {
    	String ret = "";
    	switch (col) {
    	case 0:
    		ret = bridget.getLog().get(row).date;
    		break;
    	case 1:
    		ret = bridget.getLog().get(row).comment;
    		break;
    	case 2:
    		ret = bridget.getLog().get(row).energy;
    		break;
    	default:
    		ret = "undefined";		
    	}
        return ret;
    }

    public Class getColumnClass(int c) {
        return getValueAt(0, c).getClass();
    }

    public boolean isCellEditable(int row, int col) {
            return false;
    }

}


public class JournalWindow extends JFrame implements ActionListener, SavedEventGenertor {
	
	private ArrayList<SavedListener> savedListeners = 
		new ArrayList<SavedListener>();
	
	Bridget bridget;
	Professions professions;
	
	private JComboBox activityBox;
	private JLabel whatLabel;
	private JComboBox whatBox;
	private JLabel howLabel;
	private JTextField howField;
	private JButton addButton;
	private JButton cancelButton;
	private JTable table;
	
	public JournalWindow(Bridget bridget) {
		super("Journal");
		setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
		
		this.bridget = bridget;
		professions = new Professions();
		
		JPanel inputPanel = new JPanel();
		inputPanel.setLayout(new BoxLayout(inputPanel, BoxLayout.PAGE_AXIS));
		
		table = new JTable(new JournalTableModel(bridget));
		table.setPreferredScrollableViewportSize(new Dimension(500, 250));
		JScrollPane scrollPane = new JScrollPane(table);
		inputPanel.add(scrollPane);
		
		String[] activities = { "Eating", "Fitness" };
		activityBox = new JComboBox(activities);
		activityBox.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
		inputPanel.add(activityBox);
		
		JPanel whatPanel = new JPanel();
		whatPanel.setLayout(new BoxLayout(whatPanel, BoxLayout.LINE_AXIS));
		whatLabel = new JLabel("Product: ", JLabel.RIGHT);
		String[] tempprod = { "temp" };
		whatBox = new JComboBox();
		updateWhatBox();
		whatBox.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
		whatPanel.add(whatLabel);
		whatPanel.add(whatBox);
		inputPanel.add(whatPanel);
		JPanel howPanel= new JPanel();
		howPanel.setLayout(new BoxLayout(howPanel, BoxLayout.LINE_AXIS));
		howLabel = new JLabel("Weight, kg: ", JLabel.RIGHT);
		howField = new JTextField();
		howField.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
		howPanel.add(howLabel);
		howPanel.add(howField);
		inputPanel.add(howPanel);
		
		addButton = new JButton("Add");
		addButton.setActionCommand("add clicked");
		addButton.addActionListener(this);
		inputPanel.add(addButton);
		
		JPanel mainPanel = new JPanel();
		mainPanel.setLayout(new BorderLayout());
		mainPanel.add(inputPanel, BorderLayout.NORTH);
		cancelButton = new JButton("Cancel");
		cancelButton.setActionCommand("cancel clicked");
		cancelButton.addActionListener(this);
		mainPanel.add(cancelButton, BorderLayout.SOUTH);
		
		activityBox.setActionCommand("activity changed");
		activityBox.addActionListener(this);
		
		this.setPreferredSize(new Dimension(400, 500));
		
		setContentPane(mainPanel);
		pack();		
	}
	
	private void updateWhatBox() {
		if (activityBox.getSelectedItem().equals("Eating")) {
			ArrayList<String> desProducts = professions.
			    getDesiredProducts(bridget.getProfession());
			ArrayList<String> allProducts = professions.getProducts();
			//DefaultComboBoxModel theModel = (DefaultComboBoxModel)activityBox.getModel();
			//theModel.removeAllElements();
			whatBox.removeAllItems();
			String[] products = new String[allProducts.size()];
			int cur = 0;
			while (cur < desProducts.size()) {
				products[cur] = desProducts.get(cur) + "*";
				cur++;
			}
			for (int i = 0; i < allProducts.size(); i++) {
				boolean found = false;
				for (int j = 0; j < desProducts.size(); j++) {
					if (allProducts.get(i).equals(desProducts.get(j))) {
						found = true;
					}
				}
				
				if (!found) {
					products[cur] = allProducts.get(i);
					cur++;
				}
			}
			
			for (int i = 0; i < allProducts.size(); i++) {
				whatBox.addItem(products[i]);
			}
			
		} else {
			ArrayList<String> desActs = professions.
		    getDesiredActivities(bridget.getProfession());
			ArrayList<String> allActs = professions.getActivities();
			whatBox.removeAllItems();
			String[] acts = new String[allActs.size()];
			int cur = 0;
			while (cur < desActs.size()) {
				acts[cur] = desActs.get(cur) + "*";
				cur++;
			}
			for (int i = 0; i < allActs.size(); i++) {
				boolean found = false;
				for (int j = 0; j < desActs.size(); j++) {
					if (allActs.get(i).equals(desActs.get(j))) {
						found = true;
					}
				}
			
				if (!found) {
					acts[cur] = allActs.get(i);
					cur++;
				}
			}
		
			for (int i = 0; i < allActs.size(); i++) {
				whatBox.addItem(acts[i]);
			}
		
		}
	}

	public void addSavedListener(SavedListener listener) {
		savedListeners.add(listener);
		
	}
	
	private void fireSavedEvent(SavedEvent e) {
		int j = savedListeners.size();
		if (j==0) { return; }
		for(int i=0; i<j; i++) {
			savedListeners.get(i).saved(e);
		}
	}
	
	public void actionPerformed(ActionEvent e) {
		if ("activity changed".equals(e.getActionCommand())) {
			if (activityBox.getSelectedItem().equals("Eating")) {
				whatLabel.setText("Product: ");
				howLabel.setText("Weight, g: ");
			} else {
				whatLabel.setText("Action: ");
				howLabel.setText("Time, min: ");
			}
			
			updateWhatBox();
			
		} else if ("add clicked".equals(e.getActionCommand())) {
			
			if (activityBox.getSelectedItem().equals("Eating")) {
				try {
					double weight = Double.parseDouble(howField.getText());
					StringBuffer prodBuffer = new StringBuffer(whatBox.getSelectedItem().toString());
					if (prodBuffer.charAt(prodBuffer.length() - 1) == '*') {
						prodBuffer.deleteCharAt(prodBuffer.length() - 1);
					}
					String product = prodBuffer.toString();
					double energy = professions.getProductEnergy(product);
					
					
					
					
					String comment = "Eaten " + (new Double(weight)).toString() + " g of " + 
					product;
					bridget.toLogEat(energy, weight, comment);

					
					System.out.println("eaten " + whatBox.getSelectedItem().toString() +
							           " : " + (new Double(energy)).toString());
					// TODO add energy to bridget's journal
				} catch (NumberFormatException e1) {
					JOptionPane.showMessageDialog(this, "Can't read weight:" +
							e1.getMessage());
				}
			} else {
				try {
					double minutes = Double.parseDouble(howField.getText());
					StringBuffer actBuffer = new StringBuffer(whatBox.getSelectedItem().toString());
					if (actBuffer.charAt(actBuffer.length() - 1) == '*') {
						actBuffer.deleteCharAt(actBuffer.length() - 1);
					}
					String activity = actBuffer.toString();
					double energy = professions.getActivityEnergy(activity);
					String comment = activity + " for " + 
					                 (new Double(minutes)).toString() + " minutes";
	                 whatBox.getSelectedItem().toString();
					
					System.out.println("done: " + (new Double(energy)).toString());
					
					bridget.toLogActivity(energy, minutes, comment);
					
					// TODO add energy to bridget's journal
				} catch (NumberFormatException e1) {
					JOptionPane.showMessageDialog(this, "Can't read minutes:" +
							e1.getMessage());
				}
			}
			
			SavedEvent event = new SavedEvent(this);
			event.name = "journal";
			this.fireSavedEvent(event);
			table.updateUI();
			
		}
		
	}

}
